#include "widget.h"
#include<QApplication>

#include<QIcon>
#include<QPainter>
#include<QDebug>
#include<QVector>

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{

}

Widget::Widget(int floor,hero h,int type)
{
    if(floor==21)
        h.hasPan=false;
    _floor=floor;
    initWindow();
    initMap();
    initElement();
    initHero(h);
    initPos(_floor,type,h);
    update();
}

Widget::~Widget()
{

}

void Widget::initWindow()
{
    setFixedSize(900,700);
    setWindowTitle("魔塔v1.1.2");
    //setWindowIcon(QIcon("://images/24.png"));
}

void Widget::initMap()
{
    for(int i=6;i<=16;i++){
        for(int j=1;j<=11;j++){
            int it=i-6;
            int jt=j-1;
            if(_floor<=2)
                map[it][jt].init(i,j,c.map[_floor-1][jt][it]);
            else
                map[it][jt].init(i,j,c.map[_floor-1][it][jt]);
        }
    }
}

void Widget::initElement()
{
    for(int i=6;i<=16;i++){
        for(int j=1;j<=11;j++){
            int it=i-6;
            int jt=j-1;
            int sign=0;
            sign=c.element[_floor-1][it][jt];
            if(sign>=1&&sign<=35){//怪物
                monsters[it][jt].init(i,j,sign);
                doors[it][jt].init(i,j,0);
                stages[it][jt].init(i,j,0);
                npcs[it][jt].init(i,j,0);
            }
            else if (sign>=51&&sign<=60) {//门
                monsters[it][jt].init(i,j,0);
                doors[it][jt].init(i,j,sign);
                stages[it][jt].init(i,j,0);
                npcs[it][jt].init(i,j,0);
            }
            else if (sign>60&&sign<=81) {//道具
                monsters[it][jt].init(i,j,0);
                doors[it][jt].init(i,j,0);
                stages[it][jt].init(i,j,sign);
                npcs[it][jt].init(i,j,0);
            }
            else if(sign>=36&&sign<=50){//npc
                monsters[it][jt].init(i,j,0);
                doors[it][jt].init(i,j,0);
                stages[it][jt].init(i,j,0);
                npcs[it][jt].init(i,j,sign);
            }
            else {//空地
                monsters[it][jt].init(i,j,0);
                doors[it][jt].init(i,j,0);
                stages[it][jt].init(i,j,0);
                npcs[it][jt].init(i,j,0);
            }
        }
    }
}


void Widget::modifyElement(int floor, int i, int j)
{
    c.element[floor-1][i][j]=0;
}

void Widget::initHero(hero h)
{
    heros=h;
}

void Widget::initPos(int floor,int type,hero h)
{
    if(type==1){
        heros._row=c.heroPos[floor-1][0];
        heros._col=c.heroPos[floor-1][1];
    }
    else if(type==2){
        heros._row=c.heroPos[floor-1][2];
        heros._col=c.heroPos[floor-1][3];
    }
    else {
        heros._row=h._row;
        heros._col=h._col;
    }
}


void Widget::heroMove(int row,int col)
{
    int it=row-6;
    int jt=col-1;

    if(map[it][jt]._type==0||map[it][jt]._type==4||it<0||it>10||jt<0||jt>10||doors[it][jt]._type==54||doors[it][jt]._type==56)//是墙
        return ;
    if(doors[it][jt]._type!=0&&doors[it][jt].isOpen==false){//是门
        if(heros.openDoor(doors[it][jt])){
            modifyElement(_floor,it,jt);//开门后改变数组
        }
        else {
            QMessageBox::critical(this,"开门","钥匙不足");
        }
    }
    else if (stages[it][jt]._type!=0&&stages[it][jt].isGet==false) {//是道具
        heros.pick(stages[it][jt]);
        modifyElement(_floor,it,jt);//捡到道具后改变数组
    }
    else if (monsters[it][jt]._type!=0&&monsters[it][jt]._isdead==false) {//是怪物
        if(heros.fight(monsters[it][jt])){
            QMessageBox::information(this,"胜利","获得金币"+QString::number(monsters[it][jt]._RewardM,10)+
                                                       ",获得经验"+QString::number(monsters[it][jt]._RewardE,10));

            if(monsters[it][jt]._type==32)
                QMessageBox::information(this,"魔王","有本事就来21层，让你见识我真正的实力");

            if(monsters[it][jt]._type==33){
                QMessageBox::information(this,"魔王","啊，怎么可能，我怎么可能……");
                QMessageBox::information(this,"游戏","恭喜你成功通关！");
            }

            modifyElement(_floor,it,jt);//消灭怪物后改变数组
        }
        else {
            QMessageBox::critical(this,"战斗","打不过");
        }
    }
    else if (map[it][jt]._type==2) {//上楼
        this->hide();
        if(_floor+1>heros.maxFloor)
            heros.maxFloor=_floor+1;//更新到过的最高楼层
        Widget* w=new Widget(_floor+1,heros,1);
        w->show();
    }
    else if (map[it][jt]._type==3) {//下楼
        this->hide();
        Widget* w=new Widget(_floor-1,heros,2);
        w->show();
    }
    else if(npcs[it][jt]._type!=0&&npcs[it][jt].isExist){//是npc
        npcEvent(npcs[it][jt]);
    }
    else {//是路
        heros.move(row,col);
    }
}

void Widget::npcEvent(npc &n)//碰见了npc
{
    int it=n._row-6;
    int jt=n._col-1;
    switch(n._type){
    case 36:
        s=new store(25,800,4,4);
        s->show();
        connect(s,SIGNAL(sendId(int)),this,SLOT(selectStore(int)));
        break;
    case 37:
        s=new store(100,4000,20,20);
        s->show();
        connect(s,SIGNAL(sendId(int)),this,SLOT(selectStore(int)));
        break;
    case 38:
        e=new elder(100,30,1,5,5);
        e->show();
        connect(e,SIGNAL(sendId(int)),this,SLOT(selectElder(int)));
        break;
    case 39:
        e=new elder(270,95,3,17,17);
        e->show();
        connect(e,SIGNAL(sendId(int)),this,SLOT(selectElder(int)));
        break;
    case 40:
        t=new trader(100,50,10);
        t->show();
        connect(t,SIGNAL(sendId(int)),this,SLOT(selectTrader(int)));
        break;
    case 41:
        t=new trader(-70,-35,-7);
        t->show();
        connect(t,SIGNAL(sendId(int)),this,SLOT(selectTrader(int)));
        break;
    case 42:
        elder_2();
        n.isExist=false;
        modifyElement(_floor,it,jt);
        break;
    case 43:
        trader_2();
        n.isExist=false;
        modifyElement(_floor,it,jt);
        break;
    case 44:
        elder_15(n);
        break;
    case 45:
        trader_15(n);
        break;
    case 46:
        faily(n);
        break;
    case 47:
        stealer(n);
        break;
    case 48:
        priness();
        break;
    }
}


void Widget::paintEvent(QPaintEvent *)
{
    QPainter paint(this);
    for(int i=0;i<11;i++)
    {
        for(int j=0;j<11;j++)
        {
            paint.drawPixmap(map[i][j]._row*50,map[i][j]._col*50,map[i][j].map);
        }
    }
    for(int i=0;i<11;i++)
    {
        for(int j=0;j<11;j++)
        {
            if(stages[i][j]._type!=0&&stages[i][j].isGet==false)
                paint.drawPixmap(stages[i][j]._row*50,stages[i][j]._col*50,stages[i][j].stages);
        }
    }

    for(int i=0;i<11;i++)
    {
        for(int j=0;j<11;j++)
        {
            if(doors[i][j]._type!=0&&doors[i][j].isOpen==false)
                paint.drawPixmap(doors[i][j]._row*50,doors[i][j]._col*50,doors[i][j].Door);
        }
    }

    for(int i=0;i<11;i++)
    {
        for(int j=0;j<11;j++)
        {
            if(monsters[i][j]._type!=0&&monsters[i][j]._isdead==false)
            {
                paint.drawPixmap(monsters[i][j]._row*50,monsters[i][j]._col*50,monsters[i][j].monsters);
            }
        }
    }

    for(int i=0;i<11;i++)
    {
        for(int j=0;j<11;j++)
        {
            if(npcs[i][j]._type!=0&&npcs[i][j].isExist)
            {
                paint.drawPixmap(npcs[i][j]._row*50,npcs[i][j]._col*50,npcs[i][j].npcs);
            }
        }
    }

    paint.drawPixmap(heros._row*50,heros._col*50,QPixmap(heros.path));

    paint.setFont(QFont("system",50,700));
    paint.drawText(QPoint(75,75),"等级"+QString::number(heros.level,10)+"级");
    paint.drawText(QPoint(75,125),"生命"+QString::number(heros._hp,10));
    paint.drawText(QPoint(75,175),"攻击"+QString::number(heros._attack,10));
    paint.drawText(QPoint(75,225),"防御"+QString::number(heros._defend,10));
    paint.drawText(QPoint(75,275),"金钱"+QString::number(heros.money,10));
    paint.drawText(QPoint(75,325),"经验"+QString::number(heros.exp,10));
    paint.drawText(QPoint(75,400),"红钥匙"+QString::number(heros.keyR,10)+"把");
    paint.drawText(QPoint(75,450),"蓝钥匙"+QString::number(heros.keyB,10)+"把");
    paint.drawText(QPoint(75,500),"黄钥匙"+QString::number(heros.keyY,10)+"把");

    paint.drawText(QPoint(75,550),"S:保存游戏");
    paint.drawText(QPoint(75,600),"A:读取存档");
    paint.drawText(QPoint(75,650),"SPACE:退出游戏");
    paint.drawText(QPoint(450,650),"第"+QString::number(_floor,10)+"层");
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Space:
        if( QMessageBox::question(nullptr,"退出","确定退出游戏吗",QMessageBox::Yes|QMessageBox::No)
            ==QMessageBox::Yes){
            QApplication* p=nullptr;
            p->exit(0);
        }
        break;
    case Qt::Key_Up:
        heros.path="://images/27.png";
        heroMove(heros._row,heros._col-1);
        break;
    case Qt::Key_Down:
        heros.path="://images/8.png";
        heroMove(heros._row,heros._col+1);
        break;
    case Qt::Key_Left:
        heros.path="://images/26.png";
        heroMove(heros._row-1,heros._col);
        break;
    case Qt::Key_Right:
        heros.path="://images/25.png";
        heroMove(heros._row+1,heros._col);
        break;
    case Qt::Key_J:
        if(heros.hasPan){
            windPan *w=new windPan(heros.maxFloor);
            w->show();
            connect(w,SIGNAL(sendId(int)),this,SLOT(changeFloor(int)));
        }
        break;
    case Qt::Key_A:
        if(save::getInstance()._canRead==false){
            QMessageBox::critical(this,"读取","没有存档");
        }
        else {
            for(int i=0;i<21;i++){
                for(int j=0;j<11;j++){
                    for(int k=0;k<11;k++){
                        c.map[i][j][k]=save::getInstance()._map[i][j][k];
                        c.element[i][j][k]=save::getInstance()._element[i][j][k];
                    }
                }
            }
            this->hide();
            Widget *w=new Widget(save::getInstance()._floor,save::getInstance()._h,3);
            w->show();
            QMessageBox::information(this,"读取","读取存档成功");
        }
        break;
    case Qt::Key_S:
        save::getInstance().saving(c.map,c.element,heros,_floor);
        QMessageBox::information(this,"保存","保存成功");
        break;
    case Qt::Key_H:
        if(heros.hasQuery){
            monsterQuery *m=new monsterQuery(monsters,heros);
            m->show();
            break;
        }
    default:
        break;
    }
    update();
}

void Widget::trader_2()//与二楼商人的对话
{
    QMessageBox::information(nullptr,"英雄","你已经得救了");
    QMessageBox::information(nullptr,"商人","为了表达感谢，我将这面盾牌赠送给你");
    QMessageBox::information(nullptr,"道具","获得刚盾，防御力+30");
    heros._defend+=30;
}

void Widget::elder_2()//与2楼老人对话
{
    QMessageBox::information(nullptr,"英雄","你已经得救了");
    QMessageBox::information(nullptr,"老人","这是我年轻时用过的剑，现在送给你");
    QMessageBox::information(nullptr,"道具","获得刚剑，攻击力+30");
    heros._attack+=30;
}

void Widget::trader_15(npc &n)//与15层商人对话
{
    int it=n._row-6,jt=n._col-1;;
    QMessageBox::information(nullptr,"商人","啊哈，欢迎你的到来");
    QMessageBox::information(nullptr,"商人人","我有这个游戏中最好的盾牌，可以提升120防御力，售价500金币");
    if(heros.money>=500){
        QMessageBox::information(nullptr,"英雄","好吧，这盾牌我买了");
        QMessageBox::information(nullptr,"道具","获得星光神盾，防御力+120");
        heros.money-=500;
        heros._defend+=120;
        n.isExist=false;
        modifyElement(_floor,it,jt);
    }
    else {
        QMessageBox::information(nullptr,"英雄","我的钱暂时还不够");
    }
}

void Widget::elder_15(npc &n)//与15层老人对话
{
    int it=n._row-6,jt=n._col-1;;
    QMessageBox::information(nullptr,"老人","你好，勇敢的孩子，你终于到这里了");
    QMessageBox::information(nullptr,"老人","我有一柄宝剑，可以提升120攻击力，但是需要消耗500经验");
    if(heros.exp>=500){
        QMessageBox::information(nullptr,"英雄","好吧，把剑给我吧");
        QMessageBox::information(nullptr,"道具","获得星光神剑，攻击力+120");
        heros.exp-=500;
        heros._attack+=120;
        n.isExist=false;
        modifyElement(_floor,it,jt);
    }
    else {
        QMessageBox::information(nullptr,"英雄","我的经验暂时还不够");
    }
}

void Widget::faily(npc &n)//与仙子的对话
{
    int it=n._row-6;
    int jt=n._col-1;
    if(heros.fairyTalk){
        QMessageBox::information(this,"仙子","你醒了");
        QMessageBox::information(this,"英雄","你是谁，我在哪里？");
        QMessageBox::information(this,"仙子","我是这里的仙子，你被这里的怪物打晕了");
        QMessageBox::information(this,"英雄","公主呢，我答应了国王来救公主的");
        QMessageBox::information(this,"仙子","公主还在塔里，我可以帮助你");
        QMessageBox::information(this,"仙子","不过，你要帮我找到一样东西，找到了再来这里找我");
        QMessageBox::information(this,"英雄","东西，什么东西？");
        QMessageBox::information(this,"仙子","是一个十字架，中间有一颗红色的宝石，我的魔力被封印在里面");
        QMessageBox::information(this,"仙子","切记：只有用我的魔力才能打开21层的门");
        QMessageBox::information(this,"英雄","好吧，我试试看");
        QMessageBox::information(this,"仙子","我刚刚看过了，你的剑在3层，盾在5层，十字架在7层"
                                               "塔里的其他楼层也有许多有用的道具");
        QMessageBox::information(this,"仙子","勇敢地去吧，勇士");
        modifyElement(_floor,it,jt);
        c.element[_floor-1][it+1][jt]=46;
        initElement();
        heros.fairyTalk=false;
    }
    if(heros.hasTen){
        QMessageBox::information(this,"英雄","仙子，我已经找到了那个十字架");
        QMessageBox::information(this,"仙子","做的好，我现在就授予你强大的力量！咪啦哆啦哗……");
        heros._hp=heros._hp*4/3;
        heros._defend=heros._defend*4/3;
        heros._attack=heros._attack*4/3;
        QMessageBox::information(this,"仙子","好了，我已经提升了你的能力，21层的大门已经打开");
        QMessageBox::information(this,"仙子","记住，如果没有足够的实力不要去21层，在那一层里你的所有宝物的法力都会失去作用");
        heros.hasTen=false;
        n.isExist=false;
        c.map[19][5][7]=2;
    }
}

void Widget::stealer(npc &n)//与小偷的对话
{
    int it=n._row-6;
    int jt=n._col-1;
    if(heros.stealTalk){
        QMessageBox::information(this,"英雄","你已经得救了");
        QMessageBox::information(this,"小偷","太谢谢你了，我是附近闻名的小偷jack");
        QMessageBox::information(this,"小偷","什么金银财宝我都偷过，不过这次运气不好，刚进来就被抓了");
        QMessageBox::information(this,"小偷","你救了我，那我帮你做一件事吧");
        QMessageBox::information(this,"英雄","你会开门吗");
        QMessageBox::information(this,"小偷","那当然");
        QMessageBox::information(this,"英雄","那就请你帮我打开2层的石门吧");
        QMessageBox::information(this,"小偷","那个简单，还有如果你找到了一把镶嵌有宝石的榔头，"
                                               "我还能帮你打通18层的路");
        QMessageBox::information(this,"小偷","如果你找到了那个榔头，还是来这里找我");
        heros.stealTalk=false;
        c.element[1][1][6]=0;
    }
    if(heros.hasPick&&heros.stealTalk==false){
        QMessageBox::information(this,"英雄","啊哈，你看我找到了什么");
        QMessageBox::information(this,"小偷","太好了，这个东西果然在这里，我这就帮你去修18层的路面");
        n.isExist=false;
        c.map[17][5][8]=1;
        c.map[17][5][9]=1;
        modifyElement(_floor,it,jt);
    }
}

void Widget::priness()
{
    if(heros.prinessTalk){
        QMessageBox::information(this,"英雄","公主，你已经得救了");
        QMessageBox::information(this,"公主","啊，你是来救我的吗");
        QMessageBox::information(this,"英雄","我奉国王的命令来救你，请快离开这里吧");
        QMessageBox::information(this,"公主","不，我还不想走，我要看着那个恶魔被杀死");
        QMessageBox::information(this,"公主","英雄的勇士，如果你能将那个恶魔杀死，我就和你一起出去");
        QMessageBox::information(this,"英雄","好的，我杀死恶魔后，再来这里找你");
        QMessageBox::information(this,"公主","恶魔实力强大，而且他还会变身，攻击防御都会提升一半，你一定要小心");
        QMessageBox::information(this,"公主","请一定要杀死大魔王");
        c.map[17][10][10]=2;
        initMap();
        heros.prinessTalk=false;
    }
}

void Widget::changeFloor(int i)
{
    this->hide();
    Widget *w=new Widget(i,heros,1);
    w->show();
}

void Widget::selectStore(int i)//商店购买
{

    switch(i){
    case 0:
        if(heros.money<s->_cost){
            QMessageBox::critical(nullptr,"商店","金币不足");
            return ;
        }
        heros._hp+=s->_hp;
        heros.money-=s->_cost;
        break;
    case 1:
        if(heros.money<s->_cost){
            QMessageBox::critical(nullptr,"商店","金币不足");
            return ;
        }
        heros._attack+=s->_attack;
        heros.money-=s->_cost;
        break;
    case 2:
        if(heros.money<s->_cost){
            QMessageBox::critical(nullptr,"商店","金币不足");
            return ;
        }
        heros._defend+=s->_defend;
        heros.money-=s->_cost;
        break;
    case 3:
        s->hide();
        break;
    }
    this->update();
}

void Widget::selectElder(int i)//老人购买
{
    switch(i){
    case 0:
        if(heros.exp<e->_cost1){
            QMessageBox::critical(nullptr,"老人","经验不足");
            return ;
        }
        heros.levelUp(e->_level);
        heros.exp-=e->_cost1;
        break;
    case 1:
        if(heros.exp<e->_cost2){
            QMessageBox::critical(nullptr,"老人","经验不足");
            return ;
        }
        heros._attack+=e->_attack;
        heros.exp-=e->_cost2;
        break;
    case 2:
        if(heros.exp<e->_cost2){
            QMessageBox::critical(nullptr,"老人","经验不足");
            return ;
        }
        heros._defend+=e->_defend;
        heros.exp-=e->_cost2;
        break;
    case 3:
        e->hide();
        break;
    }
    this->update();
}

void Widget::selectTrader(int i)//买钥匙
{
    switch(i){
    case 0:
        if(t->_cost1<0){
            if(heros.keyR<1){
                QMessageBox::critical(nullptr,"商人","红钥匙不足");
                return;
            }
            heros.keyR-=1;
            heros.money-=t->_cost1;
        }
        else {
            if(heros.money<t->_cost1){
                QMessageBox::critical(nullptr,"商人","金币不足");
                return ;
            }
            heros.money-=t->_cost1;
            heros.keyR+=1;
        }
        break;
    case 1:
        if(t->_cost1<0){
            if(heros.keyB<1){
                QMessageBox::critical(nullptr,"商人","蓝钥匙不足");
                return;
            }
            heros.keyB-=1;
            heros.money-=t->_cost2;
        }
        else {
            if(heros.money<t->_cost2){
                QMessageBox::critical(nullptr,"商人","金币不足");
                return ;
            }
            heros.money-=t->_cost2;
            heros.keyB+=1;
        }
        break;
    case 2:
        if(t->_cost1<0){
            if(heros.keyY<1){
                QMessageBox::critical(nullptr,"商人","黄钥匙不足");
                return;
            }
            heros.keyY-=1;
            heros.money-=t->_cost3;
        }
        else {
            if(heros.money<t->_cost3){
                QMessageBox::critical(nullptr,"商人","金币不足");
                return ;
            }
            heros.money-=t->_cost3;
            heros.keyY+=1;
        }
        break;
    case 3:
        t->hide();
        break;
    }
    this->update();
}



